% Written by Samuel Hurtado



function G3_new = unfoldg3(G3,n)

% This function is designed to "unfold" matrix g_3 generated in the third
% order approximation of a policy function in Dynare.
% Arguments:
% G3 => matrix g_3, normally stored at oo_.dr.g_3, after the computation of
% a third-order approximation;
% n => number of state variables + shocks in the model (easy: n=size(G1,2))



% replicate the order in which Dynare stored these numbers, leave zero on the elements that were discarded

G3_index=zeros(n,n,n);

mycounter=0;
totalcounter = size(G3,2);
for x=1:n
    for y=x:n
        for z=y:n
            mycounter=mycounter+1;
            tracker = mycounter/totalcounter*100;
            %disp(['tracker ' num2str(tracker) '%']);
            G3_index(x,y,z)=mycounter;
        end
    end
end



% populate G3_new, pulling out of G3 the elements designated by G3_index
% (when choosing elements of G3_index, sort index to avoid all the elements that were discarded)

G3_new = zeros(size(G3,1),n^3);

mycounter=0;
totalcounter = n*n*n;
for x=1:n
    for y=1:n
        for z=1:n
            mycounter = mycounter+1;
            tracker = mycounter/totalcounter*100;
            %disp(['tracker ' num2str(tracker) '%']);
            xyz=sort([x y z]);
            G3_new(:,mycounter)=G3(:,G3_index(xyz(1),xyz(2),xyz(3)));
        end
    end
end
